package com.ra.landlord;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import com.espirit.eap.sa.LoginUser;
import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.oosearch.Condition;
import com.googlecode.cswish.struts.spring.GenericService;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.util.bean.ModelUtil;
import com.ra.external.FeeNotificationService;
import com.ra.external.FinanceStatementService;
import com.ra.external.RoomInfoService;
import com.ra.external.RoomRetrievalService;
import com.ra.external.WeixinUserService;
import com.ra.landlord.constant.FeeRuleCalcMode;
import com.ra.landlord.constant.FeeRuleType;
import com.ra.landlord.constant.LandlordConstant;
import com.ra.util.DateTimeUtil;
import com.ra.weixin.WeixinUser;

/**
 * 合同服务
 * @author colin
 *
 */
@Service
public class AgreementService {
	
	private static final Log logger = LogFactory.getLog(AgreementService.class);

	@Resource
	private GenericService genericService;

	@Resource
	private LandlordUserService landlordUserService;

	@Resource
	private TenantUserService tenantUserService;

	@Resource
	private FeeService feeService;

	@Resource
	private MeterService meterService;
	
	@Resource
	private RoomRetrievalService retrievalService;
	
	@Resource
	private RoomInfoService roomInfoService;
	
	@Resource
	private WeixinUserService weixinUserService;
	
	@Resource
	private FinanceStatementService financeStatementService;
	
	@Resource
	private FeeNotificationService notificationService;

	@Resource
	private FeeRecordService feeRecordService;
	
	private AgreementService agreementService;
	
	private AgreementService getThis() {
		if (agreementService == null) {
			agreementService = ObjectFactory.getInstance().getBean(AgreementService.class, false);
		}
		return agreementService;
	}

	@Rest(type = "add")
	public Agreement add(ValidAgreement model) {
		// default new agreement is valid
		LandlordUser landlordUser = landlordUserService.getLoginUser();
		model.setAgent(landlordUser);

		model.adaptRentPeriod();
		model.adaptRentType();
		Agreement agreement = genericService.add(model);
		return agreement;
	}

	@Transactional
	@Rest(type = "update")
	public Agreement update(ValidAgreement model) {

		Agreement agreement = genericService.load(model);
		agreement.setLandlordUser(landlordUserService.getLoginUser().getOwnerUser());
		agreement.setRentLeaveDate(model.getRentLeaveDate());
		agreement.setReturnFee(model.getReturnFee());
		agreement.setRemark(model.getRemark());
		//agreement.setAgreementState(model.getAgreementState());

		return genericService.merge(agreement);

	}

	public PageInfo<Building> searchAndGroup() {
		// search all the agreement & list them
//		LandlordUser landlordUser = landlordUserService.getLoginUser();
//		Agreement example = new Agreement();
//		example.setLandlordUser(landlordUser.getOwnerUser());
//		List<Agreement> agreements = genericService.searchAll(example)
//				.getData();

		// group the agreements by building
		PageInfo<Building> pageInfo = new PageInfo<Building>();

		return pageInfo;
	}
	
	/**
	 * 根据租客电话获取微信用户
	 * @param phone
	 * @return
	 */
	@Rest(type = "search")
	public WeixinUser getWeixinUser(String phone){
		WeixinUser weixinUser = new WeixinUser();
		LoginUser loginUser = new LoginUser();
		loginUser.setName(phone);
		weixinUser.setLoginUser(loginUser);
		weixinUser = weixinUserService.getWeixinUser(weixinUser);
		return weixinUser;
	}
	
		/**
	 * 补全参数TenantUser
	 * @param tenantUser
	 */
	private TenantUser modifyTenantUser(TenantUser tenantUser, boolean isOldTenantUser){
		//租客新增
		TenantUser modelUser = new TenantUser();
		modelUser.setPhone(tenantUser.getPhone().trim());
		modelUser.setName(tenantUser.getName().trim());

		List<TenantUser> users = genericService.searchAll(modelUser).getData();
		if (users != null && users.size() > 0) {
			TenantUser dbTenantUser = users.get(0);
			dbTenantUser.setIdCard(tenantUser.getIdCard());
			dbTenantUser.setAddress(tenantUser.getAddress());
			dbTenantUser.setPhotoFileName(tenantUser.getPhotoFileName());
			dbTenantUser.setGender(tenantUser.getGender());
			tenantUser = dbTenantUser;
			isOldTenantUser = true;
		}else{
			tenantUser.setId(null);
			tenantUser.setLandlordUser(landlordUserService.getLoginUser().getOwnerUser());
			tenantUser.setAliase(tenantUser.getName());
			tenantUser
					.setPassword(tenantUser.getPhone());
			tenantUser.setCertificateType(0);
			tenantUser.setRegister(new Date());
		}
		
		// 绑定租客loginuser,以及是否关注微信
		WeixinUser weixinUser = getWeixinUser(tenantUser.getPhone());
		if (weixinUser != null) {
			tenantUser.setLoginUser(weixinUser.getLoginUser());
			tenantUser.setRelatedWeixin(true);
		}
		return tenantUser;
	}
	
	@Transactional
	@Rest(type = "add")
	public Agreement addAgreementNoMeter(ValidAgreement model, boolean isReserve) {
		// 先将租户add db，后面再考虑是否已经存在数据库的用户
			TenantUser tenantUser = model.getTenantUser();
			
			tenantUser = modifyTenantUser(tenantUser, false);
			
			if (isReserve) {
				// 预定时，修改房屋的状态
				updateRoomOfAgreement(model, LandlordConstant.RENT_STATE_BOOK);
				model.setTenantUser(tenantUser);
				model.setAgent(landlordUserService.getLoginUser());
				//model.setAgreementState(LandlordConstant.AGREEMENT_STATE_VALID);
			}else{
				// 出租时，修改房屋的状态
				Room room = updateRoomOfAgreement(model, LandlordConstant.RENT_STATE_ALREADY);
				// 擦，新增合约的同时要增加费用
				Fee fee = new Fee();
				fee.setRoom(room);
				double deposit = Double.valueOf(model.getDeposit());
				//第一笔费用为押金
				fee.setAmountRecv(BigDecimal.valueOf(deposit).setScale(2,BigDecimal.ROUND_HALF_UP));
				fee.setAmountActual(BigDecimal.valueOf(deposit).setScale(2,BigDecimal.ROUND_HALF_UP));
				fee.setBalance(BigDecimal.valueOf(0).setScale(2,BigDecimal.ROUND_HALF_UP));
				fee.setRental(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP));
				fee.setDateBeginRecv(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
				// 计算此次押金费用结束时间
				String dateEndRecv = DateTimeUtil.completeDateTime(model.getRentEndDate());
				fee.setDateEndRecv(dateEndRecv);
				fee.setTenantUser(tenantUser);
				//生成押金时，费用即已确认
				fee.setStatus(LandlordConstant.FEE_STATE_CONFIRMED);
				fee.setDateActual(DateTimeUtil.DATETIME_FORMAT.format(Calendar.getInstance().getTime()));
				
				fee.setLandlordUser(landlordUserService.getLoginUser().getOwnerUser());
				fee.setType(1);
				fee.setAgent(landlordUserService.getLoginUser());
				fee.setAgreement(model);
				List<Fee> lstFee = new ArrayList<Fee>(1);
				lstFee.add(fee);
				model.setFees(lstFee);
				
				// 新增合约
				model.setTenantUser(tenantUser);
				model.setAgent(landlordUserService.getLoginUser());
				//model.setAgreementState(LandlordConstant.AGREEMENT_STATE_VALID);
				if (StringUtils.isNotBlank(model.getRentBeginDate())) {
					model.setRentBeginDate(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
				}
				if (StringUtils.isNotBlank(model.getRentEndDate())) {
					model.setRentEndDate(DateTimeUtil.completeDateTime(model.getRentEndDate()));
				}
				//RentPeriod租期
//					String rentEndDate = DateTimeUtil.getEndDate(model.getRentBeginDate(),
//							Integer.valueOf(model.getRentPeriod()));
//					model.setRentEndDate(rentEndDate);
				
				// 费用增长类型，目前暂不使用
				model.setRentGrowthType(0);
				// 默认为自然月
				model.setRentMode(0);
				
				model.adaptRentPeriod();
				model.adaptRentType();
				
				//--根据信息定时发送设定判断是否需要刷新
				notificationService.indicateNotificationNeedRefresh();
			}
			model.setRentPay(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP));
			BigDecimal deposit = new BigDecimal(model.getDeposit()).setScale(2,BigDecimal.ROUND_HALF_UP);
			model.setDeposit(deposit.toString());
			BigDecimal bookPay = new BigDecimal(model.getBookPay()).setScale(2,BigDecimal.ROUND_HALF_UP);
			model.setBookPay(bookPay.toString());

			model.adaptRentType();
			
			Agreement resultAgreement = genericService.add(model);
			if (!isReserve) {
				financeStatementService.autoCreateFinanceStatement(resultAgreement.getFees().get(0));
			}
			//不管是预定还是出租，都要添加租客与房间的关系，同时冗余上合约
			addTenantRoomRelation(resultAgreement);
			
			return resultAgreement;
	}
	
	/**
	 * 新增租客房间关系
	 * @param resultAgreement
	 * @return
	 */
	private TenantRoomRelation addTenantRoomRelation(Agreement resultAgreement){
		TenantRoomRelation tenantRoomRelation = new TenantRoomRelation();
		tenantRoomRelation.setRoom(resultAgreement.getRoom());
		tenantRoomRelation.setTenantUser(resultAgreement.getTenantUser());
		tenantRoomRelation.setAgreement(resultAgreement);
		//0 - 没有关系， 1 - 房东房间关系， 2 - 管理员房间关系， 3 - 租客房间关系
		tenantRoomRelation.setType(3);
		//0表示有效，1表示无效退房的意思
		tenantRoomRelation.setExtType(0);
		return genericService.add(tenantRoomRelation);
	}
	
	/**
	 * 新增合同（预定、出租）时，修改房间
	 * @param model
	 * @param rentState
	 * @return
	 */
	private Room updateRoomOfAgreement(ValidAgreement model, Integer rentState){
		// 修改房屋的状态
		Room room = genericService.load(model.getRoom());
		// 0为出租状态
		room.setRentState(rentState);
		room.setRental(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP).toString());
		if (model.getDeposit() != null && StringUtils.isNotBlank(model.getDeposit())) {
			room.setDeposit(BigDecimal.valueOf(Double.valueOf(model.getDeposit())).setScale(2, RoundingMode.HALF_UP));
		}
		return genericService.merge(room);
	}
	

	/**
	 * 出租
	 * 
	 * @param model
	 * @param meters
	 * @return
	 * @throws ParseException 
	 */
	@Rest(type = "add")
	public Agreement addAgreement(ValidAgreement model, List<Meter> meters, boolean isReserve) {

		Agreement resultAgreement = addAgreementNoMeter(model, isReserve);
		
		// 新增抄表
		if (meters != null) {
			meterService.addMeters(meters);
		}
		
		unPublishRoom(resultAgreement);
		
		return resultAgreement;
	}
	
	public void unPublishRoom(Agreement agreement){
		try {
			//出租后，如果需要推广，则自动发布推广
			Room room = agreement.getRoom();
			if (room.getBuilding() != null) {
				retrievalService.unPublish(room);
			}
		} catch (Exception e) {
			logger.error("room unpublish is error!",e);
		}
	}

	/**
	 * 预定变出租（待继续）
	 * 
	 * @param model
	 * @param isReserve 是否是预定
	 * @return
	 */
	@Transactional
	@Rest(type = "update")
	public Agreement updateAgreement(Agreement model, boolean isReserve) {
		boolean isOldTenantUser = false;
		Agreement curAgreement = null;
		
		curAgreement = genericService.load(model);
		
		if (curAgreement == null) {
			return new Agreement();
		}
		
		// 查询用户,如果存在tenantUser.id就修改，否则就新增
		TenantUser modelUser = model.getTenantUser();
		modelUser = modifyTenantUser(modelUser, isOldTenantUser);
		curAgreement.setTenantUser(modelUser);
		
		boolean needAddFinance = false;
		if(!isReserve){
			// 出租合同修改
			if (StringUtils.isNotBlank(model.getRentBeginDate())) {
				curAgreement.setRentBeginDate(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
			}
			if (StringUtils.isNotBlank(model.getRentEndDate())) {
				curAgreement.setRentEndDate(DateTimeUtil.completeDateTime(model.getRentEndDate()));
			}
			curAgreement.setRentBeginDate(model.getRentBeginDate());
			curAgreement.setRentEndDate(model.getRentEndDate());
			curAgreement.setRentCycle(model.getRentCycle());
			curAgreement.setRentPeriod(model.getRentPeriod());
			curAgreement.adaptRentPeriod();
			curAgreement.setRentType(model.getRentType());
			curAgreement.adaptRentType();
			curAgreement.setDeposit(model.getDeposit());
			if (curAgreement.getRoom().getRentState() == LandlordConstant.RENT_STATE_BOOK) {
				//如果原房间状态为预定，则修改为出租
				curAgreement.getRoom().setRentState(LandlordConstant.RENT_STATE_ALREADY);
				//生成费用
				Fee depositFee = getDepositFee(curAgreement.getRoom(), curAgreement, curAgreement.getTenantUser());
				List<Fee> fees = curAgreement.getFees();
				if (fees == null) {
					fees = new ArrayList<Fee>();
				}
				fees.clear();
				fees.add(depositFee);
				curAgreement.setFees(fees);
				needAddFinance = true;
			}
		}
		// 出租 或者 预定的合同修改
		curAgreement.setBookPay(model.getBookPay());
		curAgreement.setRemark(model.getRemark());
		//curAgreement.setRentPay(model.getRentPay());  //合约的租金订了后，则不能修改了，只能修改房间的租金 
		if(model.getRentPay() != null){
			//修改合约的租金，同时修改房间的租金
			curAgreement.getRoom().setRental(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP).toString());
		}
		Agreement resultAgreement = genericService.merge(curAgreement);
		if (needAddFinance) {
			financeStatementService.autoCreateFinanceStatement(resultAgreement.getFees().get(0));
			unPublishRoom(resultAgreement);
		}
		if (!isOldTenantUser) {
			TenantRoomRelation tenantRoomRelation = new TenantRoomRelation();
			tenantRoomRelation.setAgreement(resultAgreement);
			tenantRoomRelation.setExtType(0);
			List<TenantRoomRelation> tenantRoomRelations = genericService.searchAll(tenantRoomRelation).getData();
			if (tenantRoomRelations != null) {
				for (TenantRoomRelation tenantRoomRelation2 : tenantRoomRelations) {
					tenantRoomRelation2.setExtType(1);
					genericService.merge(tenantRoomRelation2);
				}
			}
			addTenantRoomRelation(resultAgreement);
		}
		
		if (resultAgreement != null) {
			//更新roominfo中的租金
			roomInfoService.updateSingleRoomInfoByAgreement(resultAgreement);
			
			//修改房间后，将费用对应的房间的feerecord删除
			feeRecordService.deleteFeeRecordByRoom(resultAgreement.getRoom());
		}
		
		return resultAgreement;
	}
	
	private String getRentEndDate(String rentBeginDate, Integer tenancy, Integer tenancyType) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date _rentBeginDate = null;
		try {
			_rentBeginDate = sdf.parse(DateTimeUtil.completeDateTime(rentBeginDate));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		int needAddMonth = tenancy;
		if (Agreement.TENANCY_TYPE_YEAR.equals(tenancyType)) {
			needAddMonth *= 12;
		}
		Calendar rentEndDate = Calendar.getInstance();
		rentEndDate.setTime(_rentBeginDate);
		rentEndDate.add(Calendar.MONTH, needAddMonth);
		rentEndDate.add(Calendar.DATE, -1);
		return sdf.format(rentEndDate.getTime());
	}
	
	/**
	 * 通过model获取执行数据库的用户数据
	 * 如果数据库中存在这个用户（按身份证判断），则修改，否则新增
	 * @param modelUser
	 * @param isUpdateNew
	 * @return
	 */
	private TenantUser getDecorateTenantUser(TenantUser modelUser, boolean isGetAnotherTenantUser){
		TenantUser decorateUser = null;
		TenantUser anotherUser = tenantUserService.searchTenantUserByIdcard(modelUser.getIdCard());
		if (anotherUser != null) {
			isGetAnotherTenantUser = true;
			decorateUser = anotherUser;
			decorateUser.setGender(modelUser.getGender());
			decorateUser.setPhone(modelUser.getPhone());
			decorateUser.setName(modelUser.getName());
			decorateUser.setAddress(modelUser.getAddress());
			decorateUser.setPhotoFileName(modelUser.getPhotoFileName());
		}else{
			isGetAnotherTenantUser = false;
			modelUser.setId(null);
			decorateUser = modelUser;
			decorateUser.setRegister(new Date());
			decorateUser.setBirthday(DateTimeUtil.getBirthday(decorateUser.getIdCard()));
		}
		return decorateUser;
	}
	
	/**
	 * 获取押金费用
	 * @param room
	 * @param model
	 * @param tenantUser
	 * @return
	 */
	private Fee getDepositFee(Room room, Agreement model, TenantUser tenantUser){
		Fee fee = new Fee();
		fee.setRoom(room);
		double deposit = Double.valueOf(model.getDeposit());
		//第一笔费用为押金
		fee.setAmountRecv(BigDecimal.valueOf(deposit).setScale(2,BigDecimal.ROUND_HALF_UP));
		fee.setAmountActual(BigDecimal.valueOf(deposit).setScale(2,BigDecimal.ROUND_HALF_UP));
		fee.setBalance(BigDecimal.valueOf(0).setScale(2,BigDecimal.ROUND_HALF_UP));
		fee.setRental(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP));
		fee.setDateBeginRecv(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
		// 计算此次押金费用结束时间
		String dateEndRecv = DateTimeUtil.completeDateTime(model.getRentEndDate());
		fee.setDateEndRecv(dateEndRecv);
		fee.setTenantUser(tenantUser);
		//生成押金时，费用即已确认
		fee.setStatus(LandlordConstant.FEE_STATE_CONFIRMED);
		fee.setDateActual(DateTimeUtil.DATETIME_FORMAT.format(Calendar.getInstance().getTime()));
		
		fee.setLandlordUser(landlordUserService.getLoginUser().getOwnerUser());
		fee.setType(1);
		fee.setAgent(landlordUserService.getLoginUser());
		fee.setAgreement(model);
		
		return fee;
	}
	
	
	private void processTenantUser(ValidAgreement model) {
		TenantUser tenantUser = model.getTenantUser();
		TenantUser example = new TenantUser();
		TenantUser dbTenantUser = null;
		example.setPhone(tenantUser.getPhone().trim());
		example.setName(tenantUser.getName().trim());
		List<TenantUser> tenantUsers = genericService.searchByModel(example, Condition.DEFAULT).getData();
		if (tenantUsers.size() != 0) {
			dbTenantUser = tenantUsers.get(0);
		}
		if (dbTenantUser != null) {
			dbTenantUser.setGender(tenantUser.getGender());
			dbTenantUser.setAddress(tenantUser.getAddress());
			dbTenantUser.setPhotoFileName(tenantUser.getPhotoFileName());
			dbTenantUser.setIdCard(tenantUser.getIdCard());;
			model.setTenantUser(dbTenantUser);
		} else {
			model.getTenantUser().setId(null);
			tenantUser.setRegister(new Date());
			//tenantUser.setBirthday(DateTimeUtil.getBirthday(tenantUser.getIdCard()));
		}
		WeixinUser weixinUser = getWeixinUser(tenantUser.getPhone());
		if (weixinUser != null) {
			model.getTenantUser().setLoginUser(weixinUser.getLoginUser());
			model.getTenantUser().setRelatedWeixin(true);
		}
	}
	
	/**
	 * 出租  - 2015/8/15改造版本
	 * @param model
	 * @return
	 */
	public Agreement addRentAgreement(ValidAgreement model, List<Meter> meters) {
		ValidAgreement dbAgreement = getThis().addRentAgreementNoSync(model);
		
		//签订合约留份存根
		Agreement stubAgreement = new Agreement();
		ModelUtil.copy(dbAgreement, stubAgreement);
		stubAgreement.setAgreementState(Agreement.AGREEMENT_STATE_STUB);
		stubAgreement.setId(null);
		genericService.merge(stubAgreement);
		
		unPublishRoom(dbAgreement);
		feeService.getOrGenerateFeeRecordIfNotExists(dbAgreement);
		meterService.addMetersNew(meters);
		return dbAgreement;
	}

	@Transactional
	public ValidAgreement addRentAgreementNoSync(ValidAgreement model) {
		processTenantUser(model);
		updateRoomOfAgreement(model, LandlordConstant.RENT_STATE_ALREADY);
		model.setAgent(landlordUserService.getLoginUser());
		if (StringUtils.isNotBlank(model.getRentBeginDate())) {
			model.setRentBeginDate(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
		}
		if (StringUtils.isNotBlank(model.getRentEndDate())) {
			model.setRentEndDate(DateTimeUtil.completeDateTime(model.getRentEndDate()));
		}
		
		//押金和租金是string类型，处理为保留两位小数
		BigDecimal deposit = new BigDecimal(model.getDeposit()).setScale(2,BigDecimal.ROUND_HALF_UP);
		model.setDeposit(deposit.toString());
		BigDecimal bookPay = new BigDecimal(model.getBookPay()).setScale(2,BigDecimal.ROUND_HALF_UP);
		model.setBookPay(bookPay.toString());
		model.setRentPay(model.getRentPay().setScale(2, RoundingMode.HALF_UP));
		
		//TODO 兼容旧表结构，以后废弃vc这些代码应该删除
		model.setRentGrowthType(0);// 费用增长类型，目前暂不使用，vc默认
		model.setRentMode(0);// 默认为自然月， vc默认
		Integer tenancy = model.getTenancy();
		if (Agreement.TENANCY_TYPE_YEAR.equals(model.getTenancyType())) {
			tenancy *= 12;
		}
		model.setRentCycleType(0);
		model.setRentPeriod(tenancy.toString());
		if (model.getAdvanceNum() == null) {
			model.setAdvanceNum(3);
		}
		
		notificationService.indicateNotificationNeedRefresh();//房间出租情况变化后，定时发送短信列表需要更新
		if (model.getFees() == null) {
			model.setFees(new ArrayList<Fee>());
		}
		
		model.adaptRentTypeNew();
		
		ValidAgreement dbAgreement = genericService.merge(model);
		addTenantRoomRelation(dbAgreement);
		
		genericService.refresh(dbAgreement.getRoom());
		feeService.getOrGenerateFeeRecordIfNotExists(dbAgreement);
		
		return dbAgreement;
	}
	
	/**
	 * 预定
	 * @param model
	 * @return
	 */
	@Transactional
	public Agreement addBookAgreement(ValidAgreement model) {
		processTenantUser(model);
		updateRoomOfAgreement(model, LandlordConstant.RENT_STATE_BOOK);
		model.setAgent(landlordUserService.getLoginUser());
		if (StringUtils.isNotBlank(model.getRentBeginDate())) {
			model.setRentBeginDate(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
		}
		
		BigDecimal bookPay = new BigDecimal(model.getBookPay()).setScale(2,BigDecimal.ROUND_HALF_UP);
		model.setBookPay(bookPay.toString());
		model.setRentPay(model.getRentPay().setScale(2, RoundingMode.HALF_UP));

		model.adaptRentPeriodNew();
		model.setRentEndDate(DateTimeUtil.getFeeEndDate(model.getRentBeginDate(), 6)); //非空字段
		
		//TODO 兼容旧表结构，以后废弃vc这些代码应该删除
		model.setRentGrowthType(0);// 费用增长类型，目前暂不使用，vc默认
		model.setRentMode(0);// 默认为自然月， vc默认
		model.setRentCycleType(0);
		model.setRentType(0);
		model.setRentCycle(0);
		model.setRentPeriod("6");
		
		notificationService.indicateNotificationNeedRefresh();//房间出租情况变化后，定时发送短信列表需要更新
		Agreement dbAgreement = genericService.add(model);
		addTenantRoomRelation(dbAgreement);
		unPublishRoom(dbAgreement);
		return dbAgreement;
	}
	
	
	/**
	 * 更新合约
	 * @param model
	 * @return
	 */
	public ValidAgreement _update(ValidAgreement model) {
		return genericService.load(model);
	}
	
	public ValidAgreement _updateBook(ValidAgreement model) {
		return genericService.load(model);
	}
	
	@Transactional
	public ValidAgreement updateNew(ValidAgreement model) {
		Room dbRoom = genericService.load(model.getRoom());
		processTenantUser(model);
		
		//租金跟押金会
		updateRoomOfAgreement(model, dbRoom.getRentState());
		ValidAgreement dbValidAgreement = dbRoom.getAgreement();
		BigDecimal oldDeposit = BigDecimal.valueOf(Double.valueOf(dbValidAgreement.getDeposit()));
		dbValidAgreement.setTenantUser(model.getTenantUser());
		dbValidAgreement.setRentPay(model.getRentPay().setScale(2,BigDecimal.ROUND_HALF_UP));
		if (model.getDeposit() != null && StringUtils.isNotBlank(model.getDeposit())) {
			dbValidAgreement.setDeposit(BigDecimal.valueOf(Double.valueOf(model.getDeposit())).setScale(2, RoundingMode.HALF_UP).toString());
		}
		model.setRentBeginDate(DateTimeUtil.completeDateTime(model.getRentBeginDate()));
		if (Room.RENT_STATE_ALREADY.equals(dbRoom.getRentState())) {
			model.setRentEndDate(DateTimeUtil.completeDateTime(model.getRentEndDate()));
			dbValidAgreement.setRentBeginDate(model.getRentBeginDate());
			dbValidAgreement.setRentEndDate(model.getRentEndDate());
			dbValidAgreement.setRentCycle(model.getRentCycle());
			dbValidAgreement.setBookPay(BigDecimal.valueOf(Double.valueOf(model.getBookPay())).setScale(2, RoundingMode.HALF_UP).toString());
			dbValidAgreement.setTenancy(model.getTenancy());
			dbValidAgreement.setTenancyType(model.getTenancyType());
			dbValidAgreement.adaptRentPeriodNew();
			dbValidAgreement.setDepositNum(model.getDepositNum());
			dbValidAgreement.setPayNum(model.getPayNum());
			dbValidAgreement.adaptRentTypeNew();
			dbValidAgreement.setAdvanceNum(model.getAdvanceNum());
			dbValidAgreement.setRemark(model.getRemark());
			dbValidAgreement.setPhotoFileName(model.getPhotoFileName());
			dbValidAgreement = genericService.merge(dbValidAgreement);
			feeService.updateFeeRecordFromAgreement(dbValidAgreement, oldDeposit);
		} else {
			dbValidAgreement.setRentBeginDate(model.getRentBeginDate());
			dbValidAgreement.setBookPay(BigDecimal.valueOf(Double.valueOf(model.getBookPay())).setScale(2, RoundingMode.HALF_UP).toString());
			dbValidAgreement.setRemark(model.getRemark());
		}
		return genericService.merge(dbValidAgreement);
	}
}
